sort_failure_goals(FailureGoals, FailureGoalsC) :-
        lsort(FailureGoals, FailureGoalsC).

lsort(InList,OutList) :- lsort(InList,OutList,asc).

% sorting direction Dir is either asc or desc

lsort(InList,OutList,Dir) :-
   add_key(InList,KList,Dir),
   keysort(KList,SKList),
   rem_key(SKList,OutList).

add_key([],[],_).
add_key([(-, fail(Q,E))|Xs],[L-p((-, fail(Q,E)))|Ys],asc) :- !, 
        length(E,L), add_key(Xs,Ys,asc).
add_key([(-, fail(Q,E))|Xs],[L-p((-, fail(Q,E)))|Ys],desc) :- 
        length(E,L1), L is -L1, add_key(Xs,Ys,desc).

rem_key([],[]).
rem_key([_-p(X)|Xs],[X|Ys]) :- rem_key(Xs,Ys).



checkAs(S) :-
        find_rules(S , O),
        length(O, N),
        bb_get_value(max_num_rules, LM),
        N =< LM.
%OLD VERSION: may result in more rules
%checkAs(As, N) :- 
%        findall(
%                pr(N, S2), 
%                member(pr(N, S2), As),
%                All
%               ),
%        length(All, LR),
%        (LR > 0 ->
%                bb_get_value(max_num_rules, LM),
%                LR =< LM,
%                NN is N + 1,
%                checkAs(As, NN)
%        ;
%                true
%        ).



get_info(Info, Name, Value) :-
        member((Name, Value), Info), !.



set_info([], [(Name, Value)], Name, Value).

set_info([(Name, _VOld) | Info], [(Name, Value) | Info], Name, Value) :- !.

set_info([H | Info], [H | NewInfo], Name, Value) :-
        set_info(Info, NewInfo, Name, Value).


update_info_post_debug(Info, Info2) :- 
        get_info(Info, depth, D),
        DD is D + 1,
        set_info(Info, Info2, depth, DD), !.

update_new_state_with_new_score(NextScore, (Gs, As, Cs, Ns, Q, Info), (Gs, As, Cs, Ns, Q, Info2), Info2) :-
        set_info(Info, Info2, scr, NextScore).

check_depth(D) :-
        bb_get_value(max_depth, O3),
        number(O3), !, 
        (D =< O3 -> true ; log('DEPTH LIMIT REACHED'), fail).                    

check_depth(_D).